/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-01-26     xuxl       the first version
 */
#ifndef APPLICATIONS_RC522_H_
#define APPLICATIONS_RC522_H_

#include <stdint.h>
#include "string.h"

/////////////////////////////////////////////////////////////////////
//MF522命令字
/////////////////////////////////////////////////////////////////////
#define PCD_IDLE              0x00               //取消当前命令
#define PCD_AUTHENT           0x0E               //验证密钥
#define PCD_RECEIVE           0x08               //接收数据
#define PCD_TRANSMIT          0x04               //发送数据
#define PCD_TRANSCEIVE        0x0C               //发送并接收数据
#define PCD_RESETPHASE        0x0F               //复位
#define PCD_CALCCRC           0x03               //CRC计算

/////////////////////////////////////////////////////////////////////
//Mifare_One卡片命令字
/////////////////////////////////////////////////////////////////////
#define PICC_REQIDL           0x26               //寻天线区内未进入休眠状态
#define PICC_REQALL           0x52               //寻天线区内全部卡
#define PICC_ANTICOLL1        0x93               //防冲撞
#define PICC_ANTICOLL2        0x95               //防冲撞
#define PICC_AUTHENT1A        0x60               //验证A密钥
#define PICC_AUTHENT1B        0x61               //验证B密钥
#define PICC_READ             0x30               //读块
#define PICC_WRITE            0xA0               //写块
#define PICC_DECREMENT        0xC0               //扣款
#define PICC_INCREMENT        0xC1               //充值
#define PICC_RESTORE          0xC2               //调块数据到缓冲区
#define PICC_TRANSFER         0xB0               //保存缓冲区中数据
#define PICC_HALT             0x50               //休眠

/////////////////////////////////////////////////////////////////////
//MF522 FIFO长度定义
/////////////////////////////////////////////////////////////////////
#define DEF_FIFO_LENGTH       64                 //FIFO size=64byte
#define MAXRLEN  18

/////////////////////////////////////////////////////////////////////
//MF522寄存器定义
/////////////////////////////////////////////////////////////////////
// PAGE 0
#define RFU00                 0x00
#define CommandReg            0x01
#define ComIEnReg             0x02
#define DivlEnReg             0x03
#define ComIrqReg             0x04
#define DivIrqReg             0x05
#define ErrorReg              0x06
#define Status1Reg            0x07
#define Status2Reg            0x08
#define FIFODataReg           0x09
#define FIFOLevelReg          0x0A
#define WaterLevelReg         0x0B
#define ControlReg            0x0C
#define BitFramingReg         0x0D
#define CollReg               0x0E
#define RFU0F                 0x0F
// PAGE 1
#define RFU10                 0x10
#define ModeReg               0x11
#define TxModeReg             0x12
#define RxModeReg             0x13
#define TxControlReg          0x14
#define TxAutoReg             0x15
#define TxSelReg              0x16
#define RxSelReg              0x17
#define RxThresholdReg        0x18
#define DemodReg              0x19
#define RFU1A                 0x1A
#define RFU1B                 0x1B
#define MifareReg             0x1C
#define RFU1D                 0x1D
#define RFU1E                 0x1E
#define SerialSpeedReg        0x1F
// PAGE 2
#define RFU20                 0x20
#define CRCRsltRegM           0x21
#define CRCRsltRegL           0x22
#define RFU23                 0x23
#define ModWidthReg           0x24
#define RFU25                 0x25
#define RFCfgReg              0x26
#define GsNReg                0x27
#define CWGsCfgReg            0x28
#define ModGsCfgReg           0x29
#define TModeReg              0x2A
#define TPrescalerReg         0x2B
#define TReloadRegH           0x2C
#define TReloadRegL           0x2D
#define TCounterValueRegH     0x2E
#define TCounterValueRegL     0x2F
// PAGE 3
#define RFU30                 0x30
#define TestSel1Reg           0x31
#define TestSel2Reg           0x32
#define TestPinEnReg          0x33
#define TestPinValueReg       0x34
#define TestBusReg            0x35
#define AutoTestReg           0x36
#define VersionReg            0x37
#define AnalogTestReg         0x38
#define TestDAC1Reg           0x39
#define TestDAC2Reg           0x3A
#define TestADCReg            0x3B
#define RFU3C                 0x3C
#define RFU3D                 0x3D
#define RFU3E                 0x3E
#define RFU3F                 0x3F

#define REQ_ALL               0x52
#define KEYA                  0x60


#define ERROR_NONE                0x00    //正常
#define ERROR_NOMONEY             0x01    //余额不足
#define ERROR_NOCMD               0x02    //无效命令
#define ERROR_CHECK               0x03    //校验错误
#define ERROR_KEYA_IC             0x04    //密码错误
#define ERROR_READ_IC             0x05    //读卡失败
#define ERROR_WRITE_IC            0x06    //写卡失败
#define ERROR_WRITE_KEY_IC        0x07    //修改密码失败
#define ERROR_SET_CSTSN           0x08    //设置客户编码失败
#define ERROR_NOCARD              0x09    //IC卡不存在
#define ERROR_ATCLL               0x0A    //防冲突失败
#define ERROR_SLCT                0x0B    //选卡失败
#define ERROR_BLOCK_ADDR          0x0C    //块错误
#define ERROR_OP_TYPE             0x0D    //操作方式错误

#define FALSE           0
#define TRUE            1

#define CARD_NO_BLOCK_ADDR              4


/////////////////////////////////////////////////////////////////////
//和MF522通讯时返回的错误代码
/////////////////////////////////////////////////////////////////////
#define MI_OK                 0
#define MI_NOTAGERR           (char)(-1)
#define MI_ERR                (char)(-2)



#define AUTH_MODE_NO_ONLY                                   1
#define AUTH_MODE_ID_ONLY                                   2
#define AUTH_MODE_ID_AND_NO                             3

#define MAX_AUTH_FAIL_TIMES                             5

#define REQUEST_MAX_ATTEMPT_TIMES                   3
#define ANTI_COLLISION_MAX_ATTEMPT_TIMES    3
#define SELECT_CARD_MAX_ATTEMPT_TIMES           3
#define VALIDATE_PWD_MAX_ATTEMPT_TIMES      5
#define READ_DATA_MAX_ATTEMPT_TIMES             5

/***************************MCU RC522控制引脚***************************/
#define RC522_CS_GPIO_Port      GPIOB
#define RC522_CS_Pin            GPIO_PIN_12

#define RC522_RST_GPIO_Port     GPIOA
#define RC522_RST_Pin           GPIO_PIN_10

//#define PCD_PWR_GPIO_Port       GPIOE
//#define PCD_PWR_Pin             GPIO_PIN_15


#define RC522_PWR_OFF                                       1
#define RC522_PWR_ON                                        0


#define ENGINE_START_CONTROL    PE_Out(15)
#define ENGINE_START_LOCK           0
#define ENGINE_START_UNLOCK     1

#define LOCKED                              1
#define UNLOCKED                            0

#define CARD_NUM_DIGITS             8

#define ID_AUTH_STATE_IDLE              0
#define ID_AUTH_STATE_SEND_REQ      1
#define ID_AUTH_STATE_WAIT_ACK      2
#define ID_AUTH_STATE_FINISH            3
#define ID_AUTH_STATE_QUIT              4


#define ID_AUTH_RESULT_AUTHORIZED               0
#define ID_AUTH_RESULT_UNAUTHORIZED         1
#define ID_AUTH_RESULT_MODULE_TIMEOUT       2
#define ID_AUTH_RESULT_SERVER_TIMEOUT       3
#define ID_AUTH_RESULT_MODULE_OFFLINE       4


#define SET_CARD_NUM_STATE_IDLE                 0
#define SET_CARD_NUM_STATE_DETECT_CARD  1
#define SET_CARD_NUM_STATE_SEND_RESULT  3

#define SET_CARD_NUM_RESULT_INSTRUMENT_NO_ANSWER                0
#define SET_CARD_NUM_RESULT_NO_CARD_DETECTED                        1
#define SET_CARD_NUM_RESULT_SUCCEED                                         2

#define SEATBELT_STATE_UNAUTHORIZED             0
#define SEATBELT_STATE_WAIT_FASTEN              1
#define SEATBELT_STATE_FASTENED                     2
#define SEATBELT_STATE_UNFASTENED                   3
#define SEATBELT_STATE_REFASTENED                   4

#define UNFASTENED      1
#define FASTENED            0



typedef enum
{
    AUTH_STATUS_IDLE = 0,
    AUTH_STATUS_REQ_CARD,
    AUTH_STATUS_ANTI_COLL,
    AUTH_STATUS_SEL_CARD,
    AUTH_STATUS_AUTH_PWD,
    AUTH_STATUS_READ_CARD_NO,
    AUTH_STATUS_VFY_CARD,
    AUTH_STATUS_WAIT_CARD_AWAY,
    AUTH_STATUS_PASS,
} eAuthStatus;


extern eAuthStatus AuthStatus;
extern uint8_t FlagAuthFuncOn, CardType[2], FlagDetectCard, FlagDrvrLoginSuccess;
extern uint8_t KeyA[6], KeyB[6], CardNoBlockAddr;
extern uint8_t NumOfIcInfo, NumOfCheckItem, CheckRslt[30], CheckProgress;
extern char LastOperatorCardNo[11], LastChecklistTime[6], Checklist[20][100];
extern uint8_t card_keyA[6],card_keyB[6],card_data_read[16],card_data_write[16];
extern const uint8_t ACCESS_BITS[];
extern uint8_t flag_id_auth_timeout,flag_detect_card,flag_card_detected,flag_send_auth_req_to_module,send_auth_req_to_module_times,auth_state;
extern uint8_t auth_timer,auth_count,auth_timeout,auth_result;
extern uint8_t flag_set_card_num,set_card_num_state,flag_send_set_card_num_result;
extern uint8_t set_card_num_count,set_card_num_timer,send_set_card_num_result_times;
extern char card_num_to_write[15],set_card_num_buff[50];
extern uint8_t FlagAuthPass, AuthFailAlm, cCardNoBuf[10];


/////////////////////////////////////////////////////////////////////
//函数原型
/////////////////////////////////////////////////////////////////////
extern char PcdReset(void);
extern void PcdAntennaOn(void);
extern void PcdAntennaOff(void);
extern char PcdRequest(unsigned char req_code,unsigned char *pTagType);
extern char PcdAnticoll(unsigned char *pSnr);
extern char PcdSelect(unsigned char *pSnr);
extern char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr);
extern char PcdRead(unsigned char addr,unsigned char *pData);
extern char PcdWrite(unsigned char addr,unsigned char *pData);
extern char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue);
extern char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr);
extern char PcdHalt(void);
extern char PcdComMF522(unsigned char Command,
                 unsigned char *pInData,
                 unsigned char InLenByte,
                 unsigned char *pOutData,
                 unsigned int  *pOutLenBit);
extern void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData);
extern void WriteRawRC(unsigned char Address,unsigned char value);
extern unsigned char ReadRawRC(unsigned char Address);
extern void SetBitMask(unsigned char reg,unsigned char mask);
extern void ClearBitMask(unsigned char reg,unsigned char mask);
extern char M500PcdConfigISOType(unsigned char type);
extern void delay_10ms(unsigned int _10ms);
extern void WaitCardOff(void);
extern int RC522_Init(void);
void RC522_DeInit(void);
extern uint8_t Read_Card_SN(void);
extern uint8_t block_write(uint8_t block_addr,uint8_t *data);
extern uint8_t block_read(uint8_t block_addr);
extern uint8_t Picc_Detect(void);
extern uint8_t Read_Card_Access_Bits(uint8_t sector);
extern uint8_t Change_Common_Access_Conditions(uint8_t sector);
extern uint8_t Change_Default_Access_Conditions(uint8_t sector);
extern char Block_Add_Value(uint8_t block_addr,uint32_t add_value);
extern char Value_Block_Init(uint8_t block_addr);
extern char Block_Sub_Value(uint8_t block_addr,uint32_t sub_value);
extern char PICC_Detection(void);
extern int String_Checksum_Calculate(char *str);
extern char Set_IC_Card_Num(void);

void AuthId(void *pArg);

#endif /* APPLICATIONS_RC522_H_ */
